package com.mioto.ld.module.device.controller;

import cn.hutool.core.util.StrUtil;
import com.mioto.ld.aop.anno.BizLogAnno;
import com.mioto.ld.module.log.model.BizModuleName;
import com.mioto.ld.module.log.model.BizOperationType;
import com.mioto.ld.communication.mqtt.protocol.cache.ReportAttributeCache;
import com.mioto.ld.module.device.model.*;
import com.mioto.ld.module.statistics.StatisticsFactory;
import com.mioto.ld.module.statistics.model.DeviceFaultSearchDTO;
import com.mioto.ld.module.statistics.model.DeviceFaultStatisticsVO;
import com.mioto.ld.module.statistics.model.DeviceSaleSearchDTO;
import com.mioto.ld.module.statistics.model.DeviceSaleStatisticsVO;
import org.springframework.web.bind.annotation.*;
import com.mioto.ld.module.device.service.IDeviceService;
import com.mioto.ld.result.ResultData;
import com.mioto.ld.result.SystemTip;
import com.mioto.ld.component.BasePager;
import com.mioto.ld.exception.BasicException;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 *
 * @author mioto
 * @date 2024-05-15 16:13:50
 */
@RestController
@RequestMapping("device")
@Api(tags = "设备信息管理")
public class DeviceController {
    @Resource
    private IDeviceService deviceService;

    @GetMapping
    @ApiOperation(value="查询设备信息列表",response = Device.class)
    public ResultData list (HttpServletRequest request,Device device){
        return ResultData.success(deviceService.findList(device));
    }

    @GetMapping("/pager")
    @ApiOperation(value="分页查询设备信息",response = DevicePagerVO.class)
    @BizLogAnno(operationType = BizOperationType.PAGER,moduleName = BizModuleName.DEVICE)
    public ResultData pager (HttpServletRequest request, DeviceSearchDTO device,BasePager basePager){
        PageInfo<DevicePagerVO> pager = deviceService.findPager(device,basePager);
        Map<String, Object> result = new HashMap<>(4);
        result.put("count", pager.getTotal());
        result.put("list", pager.getList());
        return ResultData.success(result);
    }

    @GetMapping("/{column}/{value}")
    @ApiOperation(value="通过字段名查询设备信息",response = Device.class)
    public ResultData findByColumn (@PathVariable("column")String column,@PathVariable("value")Object value){
        return ResultData.success(deviceService.findByColumn(StrUtil.toUnderlineCase(column),value));
    }

    @PostMapping
    @ApiOperation(value="新增设备信息")
    public ResultData add (Device device){
        return Optional.of(deviceService.insert(device))
                .filter(count -> count > 0)
                .map(count -> ResultData.success(device))
                .orElseThrow(() -> new BasicException(SystemTip.INSERT_FAIL));
    }

    @PostMapping("/updateOwnerUser")
    @ApiOperation(value="修改设备最终用户")
    public ResultData updateOwnerUser(String deviceSn,Integer userId){
        Device device = deviceService.updateOwnerUser(deviceSn,userId);
        return  Optional.ofNullable(device)
                .map(count -> ResultData.success(device))
                .orElseThrow(() -> new BasicException(SystemTip.UPDATE_FAIL));
    }

    @PatchMapping
    @ApiOperation(value="更新设备信息 局部更新,忽略空值")
    public ResultData updateIgnoreNull (Device device){
        return Optional.of(deviceService.updateIgnoreNull(device))
                .filter(count -> count > 0)
                .map(count -> ResultData.success(device))
                .orElseThrow(() -> new BasicException(SystemTip.UPDATE_FAIL));
    }

    @PutMapping
    @ApiOperation(value="更新设备信息 整体更新")
    public ResultData update (Device device){
        return Optional.of(deviceService.update(device))
                .filter(count -> count > 0)
                .map(count -> ResultData.success(device))
                .orElseThrow(() -> new BasicException(SystemTip.UPDATE_FAIL));
    }

    @DeleteMapping("/{column}/{value}")
    @ApiOperation(value="通过字段名删除设备信息")
    public ResultData deleteByColumn (@PathVariable("column")String column,@PathVariable("value")Object value){
        return Optional.of(deviceService.deleteByColumn(StrUtil.toUnderlineCase(column),value))
                .filter(count -> count > 0)
                .map(count -> ResultData.success())
                .orElseThrow(() -> new BasicException(SystemTip.DELETE_FAIL));
    }

    @DeleteMapping("/batch")
    @ApiOperation(value="批量删除设备信息")
    public ResultData batchDelete (Integer... ids){
        return Optional.of(deviceService.batchDelete(ids))
                .filter(count -> count > 0)
                .map(count -> ResultData.success())
                .orElseThrow(() -> new BasicException(SystemTip.DELETE_FAIL));
    }

    @GetMapping("/findReportAttributes")
    @ApiOperation(value="获取设备上报属性")
    public ResultData findReportAttributes (String deviceSn){
        return ResultData.success(ReportAttributeCache.getAttributes(deviceSn));
    }

    @GetMapping("/statusStatistics")
    @ApiOperation(value="设备状态统计",response = DeviceStatusStatisticVO.class)
    public ResultData statusStatistics(DeviceSearchDTO device){
        return ResultData.success(deviceService.statusStatistics(device));
    }

    @GetMapping("/detail")
    @ApiOperation(value="设备详情",response = DeviceDetailVO.class)
    @BizLogAnno(operationType = BizOperationType.DETAIL,moduleName = BizModuleName.DEVICE)
    public ResultData findDetail(Integer deviceId){
        return ResultData.success(deviceService.findDetail(deviceId));
    }

    @GetMapping("/app/detail")
    @ApiOperation(value="app端设备详情",response = DeviceDetailAppVO.class)
    public ResultData findDetailToApp(Integer deviceId){
        return ResultData.success(deviceService.findDetailToApp(deviceId));
    }

    @GetMapping("/saleStatistics")
    @ApiOperation(value="设备销量统计",response = DeviceSaleStatisticsVO.class)
    @BizLogAnno(operationType = BizOperationType.DEVICE_SALE_STATISTIC,moduleName = BizModuleName.STATISTICS)
    public ResultData saleStatistics(DeviceSaleSearchDTO search){
        return ResultData.success(StatisticsFactory.create(search.getSearchType()).deviceSaleStatistics(search));
    }

    @GetMapping("/faultStatistics")
    @ApiOperation(value="设备故障统计",response = DeviceFaultStatisticsVO.class)
    @BizLogAnno(operationType = BizOperationType.DEVICE_FAULT_STATISTIC,moduleName = BizModuleName.STATISTICS)
    public ResultData faultStatistics(DeviceFaultSearchDTO search){
        return ResultData.success(StatisticsFactory.create(search.getSearchType()).faultStatistics(search));
    }
}